package vn.com.vega.chacha.v2;

import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.List;

import vn.com.vega.chacha.R;
import vn.com.vega.music.clientserver.JsonRingtone;
import vn.com.vega.music.objects.Ringtone;
import vn.com.vega.music.player.ChaChaProgressDialog;
import vn.com.vega.music.utils.Util;
import vn.com.vega.music.view.adapter.RingtoneListAdapter;
import vn.com.vega.music.view.adapter.RingtoneListAdapter.RegisterRingtoneInterface;
import vn.com.vega.music.view.adapter.base.AutoLoadingAdapter;
import vn.com.vega.music.view.adapter.base.AutoLoadingListener;
import vn.com.vega.music.view.custom.ChaChaDialog;
import vn.com.vega.music.view.custom.ChaChaDialog.OnCloseDialogListener;
import vn.com.vega.music.view.custom.LoadingView;
import vn.com.vega.music.view.custom.LoadingView.RetryListener;
import vn.com.vega.music.view.custom.TextBox;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.media.AudioManager;
import android.media.AudioManager.OnAudioFocusChangeListener;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnCompletionListener;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.AdapterView;
import android.widget.Button;
import android.widget.ImageButton;
import android.widget.ListView;
import android.widget.ProgressBar;
import android.widget.SeekBar;
import android.widget.TextView;
import android.widget.Toast;

public class RingtoneScreen extends ActivityBase implements OnClickListener,
		AutoLoadingListener, RegisterRingtoneInterface {
	public static final String KEY_RINGTONE_NAME = "name of ringtone";
	private ImageButton mBackBtn;
	private ListView mListRingtone;
	private TextView mtitle;
	private LoadingView mLoadingView;
	private RingtoneListAdapter mAdapter;
	private List<Object> mListRingtoneList = new ArrayList<Object>();;
	private String mSongName;
	private LoadRingtone mLoadRingtone;
	private boolean noRingtone = false;

	private ChaChaDialog mPreviewDialog;
	private ChaChaDialog mInputPhoneNumberDialog;
	private TextView mtitlePreview;
	private TextView mPricePreview;
	private ImageButton mPlaypausePreview;
	private SeekBar mSeekBarPreview;
	private ProgressBar mProgressLoadingMusic;
	private MediaPlayer mPlayer;
	private AudioManager audioManager;
	private ChaChaProgressDialog mProgressDialog;
	private Ringtone mRingtoneIspreparing;
	private Ringtone mRingtoneNeedPlay;

	@Override
	protected void onCreate(Bundle arg0) {
		// TODO Auto-generated method stub
		super.onCreate(arg0);
		setContentView(R.layout.ringtone_screen);
		mBackBtn = (ImageButton) findViewById(R.id.bt_exit);
		mBackBtn.setOnClickListener(this);
		mtitle = (TextView) findViewById(R.id.tv_title_ringtone);
		mListRingtone = (ListView) findViewById(R.id.lv_list_ringtone);
		mLoadingView = (LoadingView) findViewById(R.id.loadingView_list_ringtone);
		mProgressLoadingMusic = (ProgressBar) findViewById(R.id.progress_loading_music);
		audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
		init();
	}

	private void init() {
		Intent intent = getIntent();
		mSongName = intent.getStringExtra(KEY_RINGTONE_NAME);
		if (Util.checkStringIsemptyOrNull(mSongName)) {
			finish();
			return;
		}
		mtitle.setText("Nhạc chờ: " + mSongName);
		mLoadingView.setRetryListener(new RetryListener() {

			@Override
			public void onRetry() {
				// TODO Auto-generated method stub
				if (mLoadRingtone != null) {
					mLoadRingtone.cancel(true);
				}
				mLoadRingtone = new LoadRingtone(RingtoneScreen.this, mSongName);
				mLoadRingtone.execute();
			}
		});
		mLoadRingtone = new LoadRingtone(this, mSongName);
		mLoadRingtone.execute();
	}

	private void showDialogLoading(String message) {
		if (mProgressDialog == null) {
			mProgressDialog = new ChaChaProgressDialog(this);
		}
		mProgressDialog.setMessage(message);
		mProgressDialog.show();
	}

	@Override
	protected void onResume() {
		// TODO Auto-generated method stub
		super.onResume();
	}

	@Override
	protected void onDestroy() {
		// TODO Auto-generated method stub
		super.onDestroy();
		if (mLoadRingtone != null) {
			mLoadRingtone.cancel(true);
		}
		releasePlayer();
	}

	@Override
	public void onClick(View v) {
		// TODO Auto-generated method stub
		switch (v.getId()) {
		case R.id.bt_exit:
			finish();
			break;
		default:
			break;
		}
	}

	OnAudioFocusChangeListener audioFocusChangeListener = new OnAudioFocusChangeListener() {

		@Override
		public void onAudioFocusChange(int focusChange) {
			// TODO Auto-generated method stub
			if (focusChange == AudioManager.AUDIOFOCUS_LOSS_TRANSIENT) {
				// Pause playback
				pause();
			} else if (focusChange == AudioManager.AUDIOFOCUS_GAIN) {
				// Do nothing, because playvideo not audio.
			} else if (focusChange == AudioManager.AUDIOFOCUS_LOSS) {
				// am.unregisterMediaButtonEventReceiver(RemoteControlReceiver);
				// if (Build.VERSION.SDK_INT >= 8) {
				// audioManager.abandonAudioFocus(audioFocusChangeListener);
				// }
				// Stop playback
				releasePlayer();
			}
		}
	};

	private MediaPlayer.OnPreparedListener onPreparedListener = new MediaPlayer.OnPreparedListener() {

		@SuppressLint("NewApi")
		@Override
		public void onPrepared(MediaPlayer mp) {
			// TODO Auto-generated method stub
			if (!mPreviewDialog.isShowing()) {
				// Do not play ring tone if dialog is not show
				releasePlayer();
				return;
			}
			if (!mRingtoneIspreparing.code
					.equalsIgnoreCase(mRingtoneNeedPlay.code)) {
				// Do not play ring in case
				return;
			}
			mProgressLoadingMusic.setVisibility(View.GONE);
			mPlaypausePreview.setVisibility(View.VISIBLE);
			if (Build.VERSION.SDK_INT >= 8) {
				audioManager.requestAudioFocus(audioFocusChangeListener,
				// Use the music stream.
						AudioManager.STREAM_MUSIC,
						// Request permanent focus.
						AudioManager.AUDIOFOCUS_GAIN);
			}
			int duration = mPlayer.getDuration();
			mSeekBarPreview.setMax(duration);
			mPlayer.start();
			mPlaypausePreview.setSelected(false);
			mediaHandler.sendEmptyMessage(UPDATE_PROGRESS);
		}
	};

	private MediaPlayer.OnErrorListener onErrorListener = new MediaPlayer.OnErrorListener() {

		@Override
		public boolean onError(MediaPlayer mp, int what, int extra) {
			// TODO: do something here
			return true;
		}
	};

	private MediaPlayer.OnCompletionListener onCompletionListener = new OnCompletionListener() {

		@Override
		public void onCompletion(MediaPlayer mp) {
			// TODO Auto-generated method stub
			if (!mPreviewDialog.isShowing()) {
				return;
			}
			mSeekBarPreview.setProgress(0);
			mPlaypausePreview.setSelected(true);
			mPlayer.seekTo(0);
		}
	};

	private int getCurrentPosition() {
		if (mPlayer != null) {
			try {
				return mPlayer.getCurrentPosition();
			} catch (Exception e) {
				// TODO: handle exception
			}
		}
		return 0;
	}

	public static final int UPDATE_PROGRESS = 1;
	private MediaHandler mediaHandler = new MediaHandler(this);

	static class MediaHandler extends Handler {
		WeakReference<RingtoneScreen> ringtoneRfc;

		public MediaHandler(RingtoneScreen ring) {
			ringtoneRfc = new WeakReference<RingtoneScreen>(ring);
		}

		private boolean checkIsLive() {
			RingtoneScreen ringtoneScreen = ringtoneRfc.get();
			if (ringtoneScreen == null || ringtoneScreen.isDestroy) {
				return false;
			}
			return true;
		}

		@Override
		public void handleMessage(Message msg) {
			if (!checkIsLive()) {
				return;
			}
			RingtoneScreen ringtoneScreen = ringtoneRfc.get();
			switch (msg.what) {
			case RingtoneScreen.UPDATE_PROGRESS:
				if (ringtoneScreen.mPreviewDialog.isShowing()) {
					ringtoneScreen.mSeekBarPreview.setProgress(ringtoneScreen
							.getCurrentPosition());
				}
				sendEmptyMessageDelayed(RingtoneScreen.UPDATE_PROGRESS, 1000);
				break;

			default:
				break;
			}
		}
	}

	private void releasePlayer() {
		if (mPlayer != null) {
			try {
				audioManager.abandonAudioFocus(audioFocusChangeListener);
				mPlayer.release();
			} catch (Exception e) {
				// TODO: handle exception
			}
		}
	}

	private void showListRingtone() {
		mAdapter = new RingtoneListAdapter(this, mListRingtoneList, this);
		mListRingtone.setAdapter(new AutoLoadingAdapter(mAdapter, this));
		mListRingtone.setOnItemClickListener(onRingtoneClickListener);
	}

	private void showPreviewRingtone(final Ringtone ring) {
		if (mPreviewDialog == null) {
			OnCloseDialogListener onCloseDialogListener = new OnCloseDialogListener() {

				@Override
				public void onClose() {
					// TODO Auto-generated method stub
					mediaHandler.removeCallbacksAndMessages(null);
					releasePlayer();
				}
			};
			mPreviewDialog = new ChaChaDialog(this, onCloseDialogListener);
			mPreviewDialog.setCancelable(true);
			mPreviewDialog.setTitle(getString(R.string.setup_ringtone));
			LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
			View viewdialog = inflater.inflate(
					R.layout.view_dialog_ringtone_preview, null);
			mtitlePreview = (TextView) viewdialog
					.findViewById(R.id.tv_ringtone_title);
			mPricePreview = (TextView) viewdialog
					.findViewById(R.id.tv_ringtone_price);
			mPlaypausePreview = (ImageButton) viewdialog
					.findViewById(R.id.bt_playpause_preview_ringtone);
			mSeekBarPreview = (SeekBar) viewdialog
					.findViewById(R.id.seekbar_ringtone_progress);
			mProgressLoadingMusic = (ProgressBar) viewdialog
					.findViewById(R.id.progress_loading_music);
			mPlaypausePreview.setOnClickListener(new View.OnClickListener() {

				@Override
				public void onClick(View v) {
					// TODO Auto-generated method stub
					if (isPlayerIsPlaying()) {
						mPlaypausePreview.setSelected(true);
						pause();
					} else {
						mPlaypausePreview.setSelected(false);
						startPlay();
					}
				}
			});
			mPreviewDialog.setContentView(viewdialog);

			View.OnClickListener onRegisterListener = new OnClickListener() {

				@Override
				public void onClick(View v) {
					// TODO Auto-generated method stub
					mPreviewDialog.dismiss();
					doRegisterRingtone(ring, -1);
				}
			};

			View.OnClickListener onPresentListener = new OnClickListener() {

				@Override
				public void onClick(View v) {
					// TODO Auto-generated method stub
					mPreviewDialog.dismiss();
					showInputPhoneNumberDialog(ring);
				}
			};

			// View.OnClickListener onCancelClickListener = new
			// View.OnClickListener() {
			//
			// @Override
			// public void onClick(View v) {
			// // TODO Auto-generated method stub
			// mPreviewDialog.dismiss();
			// }
			// };
			mPreviewDialog.addButton(getString(R.string.register),
					onRegisterListener);
			mPreviewDialog.addButton(getString(R.string.gift),
					onPresentListener);
			// mPreviewDialog.addButton(getString(R.string.cancel),
			// onCancelClickListener);
		}
		mtitlePreview.setText(ring.title + " - " + ring.artist);
		mPricePreview.setText("Giá: " + ring.price);
		mPlaypausePreview.setSelected(true);
		mSeekBarPreview.setProgress(0);
		mProgressLoadingMusic.setVisibility(View.VISIBLE);
		mPlaypausePreview.setVisibility(View.INVISIBLE);
		mPreviewDialog.show();
		releasePlayer();
		mPlayer = new MediaPlayer();
		mPlayer.setOnPreparedListener(onPreparedListener);
		mPlayer.setOnErrorListener(onErrorListener);
		mPlayer.setOnCompletionListener(onCompletionListener);
		try {
			mPlayer.setDataSource(ring.streamingUrl);
			mPlayer.prepareAsync();
			mRingtoneIspreparing = ring;
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	private boolean isPlayerIsPlaying() {
		try {
			if (mPlayer != null) {
				return mPlayer.isPlaying();
			}
		} catch (Exception e) {
			// TODO: handle exception

		}
		return false;
	}

	private void startPlay() {
		try {
			if (mPlayer != null) {
				mPlayer.start();
				mediaHandler.sendEmptyMessage(UPDATE_PROGRESS);
			}
		} catch (Exception e) {
			// TODO: handle exception
		}
	}

	private void pause() {
		try {
			if (mPlayer != null) {
				mPlayer.pause();
				mediaHandler.removeCallbacksAndMessages(null);
			}
		} catch (Exception e) {
			// TODO: handle exception
		}
	}

	private AdapterView.OnItemClickListener onRingtoneClickListener = new AdapterView.OnItemClickListener() {

		@Override
		public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
				long arg3) {
			// TODO Auto-generated method stub
			Ringtone ring = (Ringtone) mAdapter.getItem(arg2);
			showPreviewRingtone(ring);
			mRingtoneNeedPlay = ring;
			mAdapter.notifyDataSetChanged();
		}
	};

	static class LoadRingtone extends AsyncTask<Void, Void, Void> {
		WeakReference<RingtoneScreen> ringtoneRfc;
		String songName;

		public LoadRingtone(RingtoneScreen ringtoneScreen, String song) {
			ringtoneRfc = new WeakReference<RingtoneScreen>(ringtoneScreen);
			this.songName = song;
		}

		private boolean checkIsLive() {
			RingtoneScreen ringtoneScreen = ringtoneRfc.get();
			if (ringtoneScreen == null || ringtoneScreen.isDestroy) {
				return false;
			}
			return true;
		}

		@Override
		protected Void doInBackground(Void... params) {
			// TODO Auto-generated method stub
			if (!checkIsLive()) {
				return null;
			}
			RingtoneScreen ringtoneScreen = ringtoneRfc.get();
			JsonRingtone jsonRingtone = JsonRingtone.loadRingtuneListBySong(
					songName, 0);
			if (jsonRingtone.isSuccess()) {
				ringtoneScreen.mListRingtoneList.addAll(jsonRingtone.ringtunes);
				if (ringtoneScreen.mListRingtoneList.size() == 0) {
					ringtoneScreen.noRingtone = true;
				}
			} else {
				ringtoneScreen.noRingtone = true;
			}
			return null;
		}

		@Override
		protected void onPostExecute(Void result) {
			// TODO Auto-generated method stub
			if (isCancelled() || !checkIsLive()) {
				return;
			}
			RingtoneScreen ringtoneScreen = ringtoneRfc.get();
			if (ringtoneScreen.noRingtone) {
				Toast.makeText(
						ringtoneScreen,
						ringtoneScreen.getString(R.string.no_ringtone_for_song),
						Toast.LENGTH_SHORT).show();
				ringtoneScreen.finish();
				return;
			}
			if (ringtoneScreen.mListRingtoneList.size() > 0) {
				ringtoneScreen.mLoadingView.loadingFinish(true, null);
				ringtoneScreen.showListRingtone();
			} /*
			 * else { ringtoneScreen.mLoadingView.loadingFinish(false, null); }
			 */
		}

		@Override
		protected void onPreExecute() {
			// TODO Auto-generated method stub
			if (!checkIsLive()) {
				return;
			}
			RingtoneScreen ringtoneScreen = ringtoneRfc.get();
			ringtoneScreen.mLoadingView.startLoading();
		}

	}

	static class EnterPhoneNumberHoder {
		TextBox mtextBox;
		Button mOkBtn;
	}

	private void showInputPhoneNumberDialog(final Ringtone ring) {
		final EnterPhoneNumberHoder hoder;
		if (mInputPhoneNumberDialog == null) {
			mInputPhoneNumberDialog = new ChaChaDialog(this, null);
			LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
			View inputView = inflater.inflate(R.layout.view_enter_phone_number,
					null);
			hoder = new EnterPhoneNumberHoder();
			hoder.mtextBox = (TextBox) inputView
					.findViewById(R.id.textBox_input_phonnumber);
			hoder.mtextBox.setTextHint("Nhập số điện thoại");
			hoder.mtextBox.setBackground(R.drawable.bg_login_edittext);
			hoder.mOkBtn = (Button) inputView
					.findViewById(R.id.bt_confirm_input_phone_number);
			inputView.setTag(hoder);
			mInputPhoneNumberDialog.setContentView(inputView);
			mInputPhoneNumberDialog
					.setTitle(getString(R.string.ringtone_enter_phone_number));
		} else {
			hoder = (EnterPhoneNumberHoder) (mInputPhoneNumberDialog
					.getContentView()).getTag();
		}
		hoder.mtextBox.setText("");
		hoder.mOkBtn.setOnClickListener(new View.OnClickListener() {

			@Override
			public void onClick(View v) {
				// TODO Auto-generated method stub
				String phone = hoder.mtextBox.getText();
				int phoneNumber = -1;
				try {
					phoneNumber = Integer.valueOf(phone);
				} catch (Exception e) {
					// TODO: handle exception
					phoneNumber = -1;
				}
				if (phoneNumber != -1) {
					mInputPhoneNumberDialog.dismiss();
					doRegisterRingtone(ring, phoneNumber);
				}
			}
		});
		mInputPhoneNumberDialog.show();
	}

	private void doRegisterRingtone(Ringtone ring, int phoneNumber) {
		RegisterRingtone registerRingtone = new RegisterRingtone(this,
				ring.code, phoneNumber, ring.title);
		registerRingtone.execute();
	}

	@Override
	public Activity getContext() {
		// TODO Auto-generated method stub
		return this;
	}

	@Override
	public List<Object> getMoreData() {
		// TODO Auto-generated method stub
		List<Object> result = new ArrayList<Object>();
		JsonRingtone jsonRingtone = JsonRingtone.loadRingtuneListBySong(
				mSongName, mAdapter.getCount());
		if (jsonRingtone.isSuccess()) {
			result.addAll(jsonRingtone.ringtunes);
		}
		return result;
	}

	static class RegisterRingtone extends AsyncTask<Void, Void, Void> {
		WeakReference<RingtoneScreen> ringtoneScreenRfc;
		String ringtoneCode;
		int phoneNumber;
		String ringName;
		String erorMessage;

		public RegisterRingtone(RingtoneScreen ringScreen, String codeRing,
				int phone, String nameRing) {
			ringtoneScreenRfc = new WeakReference<RingtoneScreen>(ringScreen);
			ringtoneCode = codeRing;
			phoneNumber = phone;
			ringName = nameRing;
		}

		private boolean checkAppIsLive() {
			RingtoneScreen ringtoneScreen = ringtoneScreenRfc.get();
			if (ringtoneScreen == null || ringtoneScreen.isDestroy) {
				return false;
			}
			return true;
		}

		@Override
		protected Void doInBackground(Void... params) {
			// TODO Auto-generated method stub
			if (!checkAppIsLive()) {
				return null;
			}
			JsonRingtone jsonRingtone = JsonRingtone.registerRingtune(
					ringtoneCode, phoneNumber);
			if (jsonRingtone.isSuccess()) {
				erorMessage = null;
			} else {
				erorMessage = jsonRingtone.getErrorMessage();
			}

			return null;
		}

		@Override
		protected void onPostExecute(Void result) {
			// TODO Auto-generated method stub
			if (isCancelled() || !checkAppIsLive()) {
				return;
			}
			RingtoneScreen ringtoneScreen = ringtoneScreenRfc.get();
			ringtoneScreen.mProgressDialog.dismiss();
			if (erorMessage == null) {
				if (phoneNumber > 0) {
					ringtoneScreen.showToast(ringtoneScreen
							.getString(R.string.register_ringtone_success)
							+ " bài "
							+ ringName
							+ " cho số điện thoại "
							+ phoneNumber);
				} else {
					ringtoneScreen.showToast(ringtoneScreen
							.getString(R.string.register_ringtone_success)
							+ " bài nhạc chờ " + ringName);
				}
			} else {
				if (phoneNumber > 0) {
					ringtoneScreen.showToast(erorMessage/*
														 * +
														 * ringtoneScreen.getString
														 * (R.string.
														 * register_ringtone_fail
														 * ) + " bài " +
														 * ringName +
														 * " cho số điện thoại "
														 * + phoneNumber
														 */);
				} else {
					ringtoneScreen.showToast(erorMessage/*
														 * + ringtoneScreen
														 * .getString(R.string.
														 * register_ringtone_fail
														 * ) + " bài nhạc chờ "
														 * + ringName
														 */);
				}
			}
		}

		@Override
		protected void onPreExecute() {
			// TODO Auto-generated method stub
			if (!checkAppIsLive()) {
				return;
			}
			RingtoneScreen ringtoneScreen = ringtoneScreenRfc.get();
			ringtoneScreen.showDialogLoading(ringtoneScreen
					.getString(R.string.start_register_ringtone));
		}

	}

	@Override
	public void registerRintone(Ringtone ring) {
		// TODO Auto-generated method stub
		doRegisterRingtone(ring, -1);
	}

	@Override
	public void presentRingtone(Ringtone ring) {
		// TODO Auto-generated method stub
		showInputPhoneNumberDialog(ring);
	}
}
